/* Project: POPS
 * CS 279, Vanderbilt University
 * by: Igor I. Ges, Michael S. Parrish, Mark E. Sakauye
 *
 *  This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


package com.popsGUI.java;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Random;

import java.util.Iterator;

import com.popsDB.java.dao.CustomerorderhistoryDao;
import com.popsDB.java.dao.CustomersDao;
import com.popsDB.java.dao.ItemsDao;
import com.popsDB.java.dao.ModificationTimesDao;
import com.popsDB.java.dao.OrdereditemsDao;
import com.popsDB.java.dao.OrdersDao;
import com.popsDB.java.dao.EmployeeDao;
import com.popsDB.java.dao.PositionsDao;
import com.popsDB.java.dao.PricesheetitemsDao;
import com.popsDB.java.dao.PricesheetsDao;
import com.popsDB.java.factory.CustomerorderhistoryDaoFactory;
import com.popsDB.java.factory.CustomersDaoFactory;
import com.popsDB.java.factory.ItemsDaoFactory;
import com.popsDB.java.factory.OrdereditemsDaoFactory;
import com.popsDB.java.factory.OrdersDaoFactory;
import com.popsDB.java.factory.EmployeeDaoFactory;
import com.popsDB.java.factory.PositionsDaoFactory;
import com.popsDB.java.factory.PricesheetitemsDaoFactory;
import com.popsDB.java.factory.PricesheetsDaoFactory;
import com.popsDB.java.dto.Customerorderhistory;
import com.popsDB.java.dto.CustomerorderhistoryPk;
import com.popsDB.java.dto.Customers;
import com.popsDB.java.dto.CustomersPk;
import com.popsDB.java.dto.EmployeePk;
import com.popsDB.java.dto.Items;
import com.popsDB.java.dto.ItemsPk;
import com.popsDB.java.dto.Ordereditems;
import com.popsDB.java.dto.Orders;
import com.popsDB.java.dto.Employee;
import com.popsDB.java.dto.Positions;
import com.popsDB.java.dto.PositionsPk;
import com.popsDB.java.dto.OrdersPk;
import com.popsDB.java.dto.Pricesheetitems;
import com.popsDB.java.dto.Pricesheets;
import com.popsDB.java.dto.PricesheetsPk;
import com.popsDB.java.exceptions.CustomerorderhistoryDaoException;
import com.popsDB.java.exceptions.CustomersDaoException;
import com.popsDB.java.exceptions.EmployeeDaoException;
import com.popsDB.java.exceptions.PositionsDaoException;
import com.popsDB.java.exceptions.ItemsDaoException;
import com.popsDB.java.exceptions.PricesheetitemsDaoException;
import com.popsDB.java.exceptions.PricesheetsDaoException;

import com.popsDB.java.exceptions.OrdereditemsDaoException;
import com.popsDB.java.exceptions.OrdersDaoException;

//import com.popsGUI.java.mainMenu;

//should be a singleton
public class Mediator {
	public final int MAX_CACHE_SIZE = 5;

	// All customer related final variables
	public final int C_MAX_CUST_NAME_LENGTH = 45;
	public final int C_MAX_ADDRESS_LENGTH = 45;
	public final int C_MAX_CITY_LENGTH = 45;
	public final int C_MAX_STATE_LENGTH = 2;
	public final int C_MAX_PHONE_NUMBER_LENGTH = 10;
	public final int C_MAX_TAX_EXEMPTION_LENGTH = 10;
	public final int C_MAX_TAX_AREA_CODE_LENGTH = 10;
	public final int C_MAX_ZIPCODE_LENGTH = 5;

	public final int FOREMAN = 3;
	public final int EXT_SALESMAN = 5; 
	public final int DRIVER = 2;
	public final int SALESMAN = 4; 
	
	// MODIFICATION TABLE STUFF
	public final int CUSTOMERS_TABLE = 0;
	public final int ITEMS_TABLE = 1;
	public final int EMPLOYEE_TABLE = 2;
	public final int PRICESHEETS_TABLE= 3;
	public final int PRICESHEETITEMS_TABLE = 4;
	public final int ORDEREDITEMS_TABLE = 5;
	public final int CUSTOMERORDERHISTORY_TABLE= 6;

	
	// All employee related final variables
	public final int E_MAX_UNIT_LENGTH = 10;
	public final int E_MAX_NAME_LENGTH = 20;

	// All price sheet related final variables
	public final int PS_MAX_NAME_LENGTH = 25;

	// All ordered items related final variables
	public final int OI_MAX_UNIT_LENGTH = 10;

	// All items related final variables
	public final int I_MAX_NAME_LENGTH = 45;
	public final int I_MAX_UNIT_LENGTH = 10;
	
	// Indexes of unit prices in the size 2 float[]
	public final int PRICE1_INDEX = 0;
	public final int PRICE2_INDEX = 1;
	
	public final float DEFAULT_MODIFIER = 1;

	public final int UPD_TIME_EMPLOYEE_TABLE_ID = 0;
	public final int UPD_TIME_ITEMS_TABLE_ID = 1;
	public final int UPD_TIME_CUSTOMERS_TABLE_ID = 2;
	public final int UPD_TIME_PRICESHEETS_TABLE_ID = 3;
	public final int UPD_TIME_POSITIONS_TABLE_ID = 4;
	
	private CustomersDao CustomersDAO;
	private ItemsDao ItemsDAO;
	private OrdereditemsDao OrderedItemsDAO;
	private OrdersDao OrdersDAO;
	private EmployeeDao EmployeeDAO;
	private PositionsDao PositionsDAO;
	private CustomerorderhistoryDao CustomerOrderHistoryDAO;
	private PricesheetsDao PriceSheetsDAO;
	private PricesheetitemsDao PriceSheetItemsDAO;
	private ModificationTimesDao ModificationTimesDAO;
	private boolean debug = true;

	//CUSTOMER
	// This list will contain only active customers.
	private ArrayList <Customers> CustomerList;
	// This list will contain all customer objects
	private ArrayList <Customers> CustomerEditList;

	//this list will contain customer names as string objects
	private String[] CustomerNames;
	private String[] CustomerEditNames;
	private int[] CustomerIDList;
	private int[] CustomerEditIDList;
	private ArrayList<Integer> CustomerBillToIDList;

	private Date[] ModificationTimes;

	private ArrayList <Positions> Positions;
	
	private ArrayList <Employee> ForemanList;
	private ArrayList <Employee> SalespersonList;
	private ArrayList <Employee> ExternalSalespersonList;
	private ArrayList <Employee> EmployeeList;
	private ArrayList <Items> ItemsList;
	private ArrayList <Items> ActiveItemsList;
	private HashMap<Integer, Items> ItemsMap;
	private ArrayList <Employee> DriverList;

	private ArrayList <TemplateCacheItem> PriceSheetTemplateCache;
	private LinkedList <CompletePricesheetCacheItem> PriceSheetCache;

	private ArrayList <Pricesheets> PriceSheetTemplates;
	private ArrayList <Pricesheets> PriceSheets;
	private ArrayList <Pricesheets> EditPriceSheets;

	DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm");


	private static final Mediator INSTANCE = new Mediator();
	// Private constructor prevents instantiation from other classes

	private Mediator() 
	{
		if (debug)
		{
			System.out.print("MEDIATOR STARTED WORKING\n");
		}

		CustomersDAO = CustomersDaoFactory.create();
		ItemsDAO = ItemsDaoFactory.create();
		OrderedItemsDAO = OrdereditemsDaoFactory.create();
		OrdersDAO = OrdersDaoFactory.create();
		EmployeeDAO = EmployeeDaoFactory.create();
		PositionsDAO = PositionsDaoFactory.create();
		CustomerOrderHistoryDAO = CustomerorderhistoryDaoFactory.create();
		PriceSheetsDAO = PricesheetsDaoFactory.create();
		PriceSheetItemsDAO = PricesheetitemsDaoFactory.create();

		// CUSTOMER LIST MIGHT NOT BE NECESSARY !!!!!!!
		CustomerList = new ArrayList<Customers>();
		CustomerEditList = new ArrayList<Customers>();

		DriverList = new ArrayList<Employee>();
		ForemanList = new ArrayList<Employee>();
		ExternalSalespersonList = new ArrayList<Employee>();
		SalespersonList = new ArrayList<Employee>();
		EmployeeList = new ArrayList<Employee>();
		PriceSheets = new ArrayList <Pricesheets>();
		PriceSheetTemplates = new ArrayList <Pricesheets>();
		EditPriceSheets = new ArrayList <Pricesheets>();


		PriceSheetTemplateCache = new ArrayList <TemplateCacheItem> ();
		PriceSheetCache = new LinkedList <CompletePricesheetCacheItem> ();

		ItemsList = new ArrayList<Items>();
		ActiveItemsList = new ArrayList<Items>();
		//ItemsMap = new HashMap<Integer, Items>();

		this.reloadDB();


	}

	public static Mediator getInstance() {
		return INSTANCE;
	}

	public String[] getCustomerNames() {
		return CustomerNames;
	}

	public String[] getCustomerEditNames() {
		return CustomerEditNames;
	}
	public ArrayList<Customers> getCustomerEditList() {
		return CustomerEditList;
	}

	public int[] getCustomerIDList() {
		return CustomerIDList;
	}

	public int[] getCustomerEditIDList() {
		return CustomerEditIDList;
	}

	public ArrayList<Employee> getExternalSalespersonList(){
		return ExternalSalespersonList;
	}

	public ArrayList<Employee> getSalespersonList(){
		return SalespersonList;
	}

	public ArrayList<Employee> getForemanList(){
		return ForemanList;
	}

	public int getItemsListLength() {
		return ItemsList.size();
	}

	public ArrayList<Items> getItemsList() {
		return ItemsList;
	}
	
	public ArrayList<Items> getItemsListCopy() {
		ArrayList<Items> ItemsList2 = new ArrayList<Items>();
		for (int i = 0; i < ItemsList.size(); i++)
		{
			Items _itm = new Items();
			_itm.setCost(ItemsList.get(i).getCost());
			_itm.setIsActive(ItemsList.get(i).getIsActive()) ;
			_itm.setItemDescription(ItemsList.get(i).getItemDescription()) ;
			_itm.setItemID(ItemsList.get(i).getItemID()) ;
			_itm.setItemName(ItemsList.get(i).getItemName()) ;
			_itm.setOtherUnitName(ItemsList.get(i).getOtherUnitName()) ;
			_itm.setOtherUnitPrice(ItemsList.get(i).getOtherUnitPrice()) ;
			_itm.setUnitName(ItemsList.get(i).getUnitName()) ;
			_itm.setUnitPrice(ItemsList.get(i).getUnitPrice()) ;
			
			ItemsList2.add(_itm);
		}
		return ItemsList2;
	}

	public int getActiveItemsListLength() {
		return ActiveItemsList.size();
	}

	public ArrayList<Items> getActiveItemsList() {
		return ActiveItemsList;
	}

	public ArrayList <Pricesheets> getPriceSheets()
	{
		return PriceSheets;
	}

	public ArrayList <Pricesheets> getPriceSheetTemplates()
	{
		return PriceSheetTemplates;
	}

	public ArrayList <Pricesheets> getEditPriceSheets() {
		return EditPriceSheets;
	}

	// Fill the CustomerBillToIDList with all available bill to id's.
	public ArrayList<Integer> getCustomerBillToIDList(int custID) {
		CustomerBillToIDList = new ArrayList<Integer>();
		for (int i = 0; i < CustomerEditList.size(); i++) {
			if (CustomerEditList.get(i).getIsActive() == 1 || CustomerEditList.get(i).getCustomerID() == custID) {
				CustomerBillToIDList.add(CustomerEditList.get(i).getCustomerID());
			}
		}
		return CustomerBillToIDList;
	}

	/*
	 * fetchCustomers
	 * grabs the Customers from DB and stores them in CustomerList object
	 * then updates the CustomerNames to reflect the changes. The function
	 * is to be called when there is a conflict in stored version and DB
	 * and daily to update the info.
	 */





	public void reloadDB()
	{//RENAME TO RELAODDB
		//cleanup
		EmployeeList.clear();
		ExternalSalespersonList.clear();
		DriverList.clear();
		ForemanList.clear();
		SalespersonList.clear();
		ItemsList.clear();
		ActiveItemsList.clear();
		CustomerEditList.clear();
		CustomerList.clear();
		PriceSheets.clear();
		PriceSheetTemplates.clear();
		EditPriceSheets.clear();

		try 
		{
			//get list of customers from DAO
			Customers[] _customers = CustomersDAO.findAll();

			// Find the number of active customers.
			int activeCustomers = 0;
			for (int i = 0; i < _customers.length; i++){
				if (_customers[i].getIsActive() == 1){
					activeCustomers = activeCustomers + 1;
				}
			}
			// Create an appropriate sized array of CustomerNames 
			CustomerNames = new String[activeCustomers];
			CustomerIDList = new int[activeCustomers];

			// Fill the CustomerList and Customer names with the appropriate number of customers.
			int namesCount = 0;
			for (int i = 0; i < _customers.length; i++) {
				if (_customers[i].getIsActive() == 1){
					CustomerList.add(_customers[i]);
					CustomerNames[namesCount]=_customers[i].getCustomerName();
					CustomerIDList[namesCount] = _customers[i].getCustomerID();
					namesCount++;
				}
			}

			// Create an appropriate sized array of CustomerNames 
			CustomerEditNames = new String[_customers.length];
			CustomerEditIDList = new int [_customers.length];

			// Fill the CustomerEditNames with all available customers.
			for (int i = 0; i < _customers.length; i++) {
				CustomerEditList.add(_customers[i]);
				CustomerEditNames[i]=_customers[i].getCustomerName();
				CustomerEditIDList[i]=_customers[i].getCustomerID();
			}




			// getEmployees of all sorts and kinds
			Employee[] _employee = EmployeeDAO.findAll();

			for (int i = 0; i <_employee.length; i++)
			{
				this.EmployeeList.add(_employee[i]);

				
				if(_employee[i].getPositionID() == EXT_SALESMAN)
				{
					this.ExternalSalespersonList.add(_employee[i]);
				}

				if(_employee[i].getPositionID() == DRIVER)
				{
					DriverList.add(_employee[i]);
				}
				if(_employee[i].getPositionID() == FOREMAN)
				{
					ForemanList.add(_employee[i]);
				}
				if(_employee[i].getPositionID() == SALESMAN)
				{
					this.SalespersonList.add(_employee[i]);
				}
			}



			// gather a list of items
			Items[] _items = ItemsDAO.findAll();
			ItemsMap = new HashMap<Integer, Items>(_items.length);
			for (int i = 0; i <_items.length; i++)
			{
				this.ItemsList.add(_items[i]);
				if (_items[i].getIsActive() == 1) {
					ActiveItemsList.add(_items[i]);
				}
				ItemsMap.put(_items[i].getItemID(), _items[i]);
			}
			

			Pricesheets[] _pricesheets = this.PriceSheetsDAO.findAll();
			for (int i = 0; i < _pricesheets.length; i++)
			{
				if(_pricesheets[i].getParentPriceSheetID() != 0)
				{
					this.PriceSheets.add(_pricesheets[i]);
				}
				else
				{
					this.PriceSheetTemplates.add(_pricesheets[i]);
				}
				this.EditPriceSheets.add(_pricesheets[i]);
			}


			refillTemplateCache();


		}
		catch (CustomersDaoException e) 
		{
			// TODO Auto-generated catch block
			if(debug)
			{
				System.out.println("dbfetch exception in Customer DAO");
			}
			e.printStackTrace();
		}
		catch (EmployeeDaoException e)
		{
			if(debug)
			{
				System.out.println("dbfetch exception in Employee DAO");
			}
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ItemsDaoException e) {

			if(debug)
			{
				System.out.println("dbfetch exception in Items DAO");
			}
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (PricesheetsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}



	}


	//NAME: getCustomerEditID(String NameSTR) 
	//IN:   customer name as a string
	//OUT:	returns the customer edit it
	//FUNC: returns the CustomerID for the given Customer Name in the NameSTR
	//		if the NameSTR has an incorrect Customer ID ... HAS TO BE DEALT WITH
	public int getCustomerEditID(String NameSTR)
	{
		if(debug)
		{
			System.out.println("NameSTR = " + NameSTR);
		}

		for (int i = 0;i < CustomerEditList.size();i++)
		{
			//TODO:this has to be tested
			if (NameSTR.equals(CustomerEditList.get(i).getCustomerName()))
			{
				if (debug)
				{
					System.out.println("CustomerName = " + CustomerEditList.get(i).getCustomerName());
					System.out.println("CustomerID = " + CustomerEditList.get(i).getCustomerID() );
				}
				return CustomerEditList.get(i).getCustomerID();
			}
		}

		//or can be done through DB ... we should do some performance testing to see
		/*	try {
		Customers[] CustArr = CustomersDAO.findWhereCustomerNameEquals(NameSTR);
		if(CustArr.length > 1)
		{
			//error because there should only be one customer with such name
			return -1;
		}
		return CustArr[0].getCustomerID();



	} 
	catch (CustomersDaoException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}*/

		//TODO: some sort of exception if ID is not found

		if (debug)
		{
			System.out.println("COULDN'T FIND S**T. kicking back -1 ");
		}
		return -1;

	}


	//NAME: getCustomerID(String NameSTR)
	//IN:   string with the name of the customer
	//OUT:  returns the customer id
	//FUNC: returns the CustomerID for the given Customer Name in the NameSTR
	//		if the NameSTR has an incorrect Customer ID ... HAS TO BE DEALT WITH	
	public int getCustomerID(String NameSTR)
	{
		//can be done through customerList but will probably be too slow to bother
		if(debug)
		{
			System.out.println("NameSTR = " + NameSTR);
		}

		for (int i = 0;i < CustomerList.size();i++)
		{
			//TODO:this has to be tested
			if (NameSTR.equals(CustomerList.get(i).getCustomerName()))
			{
				if (debug)
				{
					System.out.println("CustomerName = " + CustomerList.get(i).getCustomerName());
					System.out.println("CustomerID = " + CustomerList.get(i).getCustomerID() );
				}
				return CustomerList.get(i).getCustomerID();
			}
		}

		//or can be done through DB ... we should do some performance testing to see
		/*	try {
		Customers[] CustArr = CustomersDAO.findWhereCustomerNameEquals(NameSTR);
		if(CustArr.length > 1)
		{
			//error because there should only be one customer with such name
			return -1;
		}
		return CustArr[0].getCustomerID();



	} 
	catch (CustomersDaoException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}*/

		//TODO: some sort of exception if ID is not found

		if (debug)
		{
			System.out.println("COULDN'T FIND S**T. kicking back -1 ");
		}
		return -1;

	}







	//////////////////////////// Seth Changes ///////////////////////////////
	//NAME: getCustomerIsActive
	//IN:   takes a customer id as an integer
	//OUT:  returns true if the customer is active. false otherwise
	//FUNC: Checks if the given customer is active. returns true if the 
	//		customer is active. false otherwise
	public boolean getCustomerIsActive(int CustID) {
		for (int i = 0; i < CustomerList.size(); i++) 
		{
			if (CustomerList.get(i).getCustomerID() == CustID) {
				if (CustomerList.get(i).getIsActive() == 1)
				{
					return true;
				}
			}
		}
		return false;
	}


	//NAME: checkCustomerDependencies
	//IN:   takes a customer id as an integer
	//OUT:  returns true if there are dependencies and false otherwise
	//FUNC: Checks if the given customer has other customers routing their
	// 		payments to them.
	public boolean checkCustomerDependencies(int CustID) {
		for (int i = 0; i < CustomerList.size(); i++) {
			if (CustomerList.get(i).getBillingID() == CustID && 
					CustomerList.get(i).getCustomerID() != CustID) {
				return true;

			}
		}
		return false;
	}

	//NAME: getCustomerDependencies
	//IN:   takes a customer id as an integer
	//OUT:  returns an arraylsit of string with all customer dependencies
	//FUNC: Creates a list of all customers routing their payments to a 
	// 		particular customer.
	public ArrayList<String> getCustomerDependencies(int CustID) {
		ArrayList<String> failcode = new ArrayList<String>();
		for (int i = 0; i < CustomerList.size(); i++) {
			if (CustomerList.get(i).getBillingID() == CustID && 
					CustomerList.get(i).getCustomerID() != CustID) {
				failcode.add(CustomerList.get(i).getCustomerName());
			}
		}
		return failcode;		
	}

	//NAME: checkIfCustomerIDExists
	//IN:   takes a customer id as an integer
	//OUT:  returns true if the customer with this id exists, false otherwise
	//FUNC: Finds if the customerID already exists before saving the database.
	//TODO: SETH THIS DOESN'T WORK if you have more that two users in DB it will 
	//		eventually blow up
	public boolean checkIfCustomerIDExists(int CustID){
		if(debug)
		{
			System.out.println("CustID = " + CustID);
		}

		for (int i = 0;i < CustomerList.size();i++)
		{
			if (CustID == CustomerList.get(i).getCustomerID())
			{
				if (debug)
				{
					System.out.println("List Number " + i);
				}
				return true;
			}
		}
		if (debug)
		{
			System.out.println("COULDN'T FIND THE CustomerID. throwing -1 ");
		}

		return false;
	}


	//NAME: getCustomerListNumber
	//IN: 	customer id as an integer  
	//OUT:
	//FUNC: Gets the list number of the current customer to make subsequent calls
	//		easier and more efficient (for active customers only)
	public int getCustomerListNumber(int CustID){
		if(debug)
		{
			System.out.println("CustID = " + CustID);
		}

		for (int i = 0;i < CustomerList.size();i++)
		{
			if (CustID == CustomerList.get(i).getCustomerID())
			{
				if (debug)
				{
					System.out.println("List Number " + i);
				}
				return i;
			}
		}
		if (debug)
		{
			System.out.println("COULDN'T FIND THE LIST NUMBER. throwing -1 ");
		}
		return -1;
	}

	//NAME: getCustomerEditListNumber
	//IN:   customer id as an int
	//OUT:  
	//FUNC: Gets the list number of the current customer to make subsequent calls
	//		easier and more efficient (for entire list of customers)
	public int getCustomerEditListNumber(int CustID){
		if(debug)
		{
			System.out.println("CustID = " + CustID);
		}

		for (int i = 0;i < CustomerEditList.size();i++)
		{
			if (CustID == CustomerEditList.get(i).getCustomerID())
			{
				if (debug)
				{
					System.out.println("List Number " + i);
				}
				return i;
			}
		}
		if (debug)
		{
			System.out.println("COULDN'T FIND THE LIST NUMBER. throwing -1 ");
		}
		return -1;
	}


	////////////// Updating Customer Fields /////////////////////////
	//TODO: this is horrific coupling
	public String getCustomerName(int i){
		return CustomerList.get(i).getCustomerName();
	}

	public String getCustomerAddress1(int i){
		return CustomerList.get(i).getAddressLine1();
	}

	public String getCustomerAddress2(int i){
		return CustomerList.get(i).getAddressLine2();
	}

	public String getCustomerCity(int i){
		return CustomerList.get(i).getCity();
	}

	public String getCustomerState(int i){
		return CustomerList.get(i).getState();
	}

	public String getCustomerZip(int i){
		return CustomerList.get(i).getZipCode();
	}

	public String getCustomerPhone1(int i){
		return CustomerList.get(i).getPhoneNum1();
	}

	public String getCustomerPhone2(int i){
		return CustomerList.get(i).getPhoneNum2();
	}

	public String getCustomerFax(int i){
		return CustomerList.get(i).getFaxNum();
	}

	public String getCustomerDirections(int i){
		return CustomerList.get(i).getDirections();
	}

	public int getCustomerHistoryInterval(int i) {
		return CustomerList.get(i).getHistoryInterval();
	}

	public String getCustomerForeman (int i)
	{
		int foremanID = CustomerList.get(i).getForemanID();

		for (int j = 0; j < EmployeeList.size(); j++)
		{
			if (EmployeeList.get(j).getEmployeeID() == foremanID)
				return EmployeeList.get(j).getLastName();
		}

		return "Could not find foreman!";
	}

	public String getCustomerSalesperson(int i)
	{
		int salespersonID = CustomerList.get(i).getSalespersonID();

		for (int j = 0; j < EmployeeList.size(); j++)
		{
			if (EmployeeList.get(j).getEmployeeID() == salespersonID)
				return EmployeeList.get(j).getLastName();
		}

		return "Could not find salesperson!";
	}


	public String getCustomerExternalSalesperson(int i)
	{
		int extSalespersonID = CustomerList.get(i).getExternalSalespersonID();

		for (int j = 0; j < EmployeeList.size(); j++)
		{
			if (EmployeeList.get(j).getEmployeeID() == extSalespersonID)
				return EmployeeList.get(j).getLastName();
		}

		return "Could not find external salesperson!";
	}

	// Gets Customer info when editing in Customer screen.
	public String getCustomerEditName(int i){
		return CustomerEditList.get(i).getCustomerName();
	}

	public String getCustomerEditAddress1(int i){
		return CustomerEditList.get(i).getAddressLine1();
	}

	public String getCustomerEditAddress2(int i){
		return CustomerEditList.get(i).getAddressLine2();
	}

	public String getCustomerEditCity(int i){
		return CustomerEditList.get(i).getCity();
	}

	public String getCustomerEditState(int i){
		return CustomerEditList.get(i).getState();
	}

	public String getCustomerEditZip(int i){
		return CustomerEditList.get(i).getZipCode();
	}

	public String getCustomerEditPhone1(int i){
		return CustomerEditList.get(i).getPhoneNum1();
	}

	public String getCustomerEditPhone2(int i){
		return CustomerEditList.get(i).getPhoneNum2();
	}

	public String getCustomerEditFax(int i){
		return CustomerEditList.get(i).getFaxNum();
	}

	public int getCustomerEditHistoryInterval(int i) {
		return CustomerEditList.get(i).getHistoryInterval();
	}

	public String getCustomerEditDirections(int i){
		return CustomerEditList.get(i).getDirections();
	}

	public boolean getIsCustomerActive(int i) {
		if (CustomerEditList.get(i).getIsActive() == 0) {
			return false;
		}
		else {
			return true;
		}
	}

	public String getCustomerEditForeman (int i)
	{
		int foremanID = CustomerEditList.get(i).getForemanID();

		for (int j = 0; j < EmployeeList.size(); j++)
		{
			if (EmployeeList.get(j).getEmployeeID() == foremanID)
				return EmployeeList.get(j).getLastName();
		}

		return "Could not find foreman!";
	}

	public String getCustomerEditSalesperson(int i)
	{
		int salespersonID = CustomerEditList.get(i).getSalespersonID();

		for (int j = 0; j < EmployeeList.size(); j++)
		{
			if (EmployeeList.get(j).getEmployeeID() == salespersonID)
				return EmployeeList.get(j).getLastName();
		}

		return "Could not find salesperson!";
	}


	public String getCustomerEditExternalSalesperson(int i)
	{
		int extSalespersonID = CustomerEditList.get(i).getExternalSalespersonID();

		for (int j = 0; j < EmployeeList.size(); j++)
		{
			if (EmployeeList.get(j).getEmployeeID() == extSalespersonID)
				return EmployeeList.get(j).getLastName();
		}

		return "Could not find external salesperson!";
	}

	// Returns the price sheet ID for the given customer, or -1 if not found
	public int getCustomerPriceSheetID(int custID) {
		try {
			Customers cust = this.CustomersDAO.findByPrimaryKey(custID);
			return cust.getPriceSheet();
		} catch (CustomersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		// If we get here the customer was never assigned a price sheet
		return -1;
	}
	
	//TODO what is this stuff? what does it do?
	public String getCustomerEditPriceSheetContact(int CustID) {
		int priceSheetID = CustomerEditList.get(CustID).getPriceSheet();
		System.out.println("priceSheetID = " + priceSheetID);

		for (int i = 0; i < EditPriceSheets.size(); i++) {
			if (EditPriceSheets.get(i).getPriceSheetID() == priceSheetID) {
				return EditPriceSheets.get(i).getPriceSheetName();
			}
		}
		return "Could not find price sheet!";
	}

	public String getCustomerPriceGroupCode(int CustID) {
		int priceGroupCode = CustomerEditList.get(CustID).getPriceSheetTemplate();

		for (int i = 0; i < PriceSheetTemplates.size(); i++) {
			if (PriceSheetTemplates.get(i).getPriceSheetID() == priceGroupCode) {
				return PriceSheetTemplates.get(i).getPriceSheetName();
			}
		}
		return "Could not find price group code!";
	}

	// Returns the Customer's Bill-To ID.
	public int getCustomerEditBillToID(int i) {
		int billToCustID = CustomerEditList.get(i).getBillingID();
		for (int j = 0; j < CustomerEditList.size(); j++)
		{
			if (CustomerEditList.get(j).getCustomerID() == billToCustID) {
				return CustomerEditList.get(j).getCustomerID();
			}
		}
		return -1;	
	}

	// Checks whether or not the given Bill to ID for the customer maps to a
	// customer that is active or maps to itself. 
	public boolean checkCustomerBillToID(int i) {
		int billToCustID = CustomerEditList.get(i).getBillingID();
		if (billToCustID == CustomerEditList.get(i).getCustomerID()) {
			return true;
		}
		for (int j = 0; j < CustomerList.size(); j++)
		{
			if (CustomerList.get(j).getCustomerID() == billToCustID) {
				if (CustomerList.get(j).getIsActive() == 1) {
					return true;
				}
			}
		}
		return false;
	}

	public boolean checkCustomerEmployeeID(String name) {
		try {
			Employee[] emp = EmployeeDAO.findWhereLastNameEquals(name);
			if (emp[0].getIsActive() == 1) {
				return true;
			}
			else {
				return false;
			}
		} catch (EmployeeDaoException e) {
			e.printStackTrace();
			return false;
		}
	}


	/////// End Updating Customer Fields ////////////////


	////////// Employee Fields ///////////////////
	//NAME: getEmployeeID(String NameSTR)
	//IN:   string with the name of the employee
	//OUT:  returns the employee id
	//FUNC: returns the EmployeeID for the given Employee Name in the NameSTR
	//		if the NameSTR has an incorrect Employee ID ... HAS TO BE DEALT WITH	
	public int getEmployeeID(String NameSTR)
	{
		int comma = NameSTR.indexOf(',');
		String last = NameSTR.substring(0, comma);
		String first = NameSTR.substring(comma+2);
		
		System.out.println("FIRST" + first);
		System.out.println("LAST" + last);
		
		//can be done through customerList but will probably be too slow to bother
		if(debug)
		{
			System.out.println("NameSTR = " + NameSTR);
		}

		for (int i = 0;i < EmployeeList.size();i++)
		{
			//TODO:this has to be tested
			if (last.equals(EmployeeList.get(i).getLastName())
					&& first.equals(EmployeeList.get(i).getFirstName()))
			{
				if (debug)
				{
					System.out.println("EmployeeLastName = " + EmployeeList.get(i).getLastName());
					System.out.println("EmployeeFirstName = " + EmployeeList.get(i).getFirstName());
					System.out.println("EmployeeID = " + EmployeeList.get(i).getEmployeeID() );
				}
				return EmployeeList.get(i).getEmployeeID();
			}
		}

		if (debug)
		{
			System.out.println("COULDN'T FIND ANYTHING. kicking back -1 ");
		}
		return -1;

	}

	public int getEmployeeListNumber (int EmpID) {
		if(debug)
		{
			System.out.println("EmpID = " + EmpID);
		}

		for (int i = 0;i < EmployeeList.size();i++)
		{
			if (EmpID == EmployeeList.get(i).getEmployeeID())
			{
				if (debug)
				{
					System.out.println("List Number " + i);
				}
				return i;
			}
		}
		if (debug)
		{
			System.out.println("COULDN'T FIND THE LIST NUMBER. throwing -1 ");
		}
		return -1;
	}

	public boolean getEmployeeIsActive(int i) {
		return (EmployeeList.get(i).getIsActive() == 1);
	}

	public String[] getEmployeeNames() {
		String[] names = new String[EmployeeList.size()];
		for (int i = 0; i < EmployeeList.size(); i++) {
			names[i] = EmployeeList.get(i).getLastName() + ", " + EmployeeList.get(i).getFirstName();
		}
		return names;
	}

	//NAME: doesEmpLastNameExist
	//IN:   last name of a employee as a string
	//OUT:  a boolean with result status
	//FUNC:	Returns true if the employee name exists, false otherwise. Returns 
	//		false on error.
	public boolean doesEmpLastNameExist(String name) 
	{
		try {
			Employee[] emp = EmployeeDAO.findWhereLastNameEquals(name);

			// If the array isn't empty, the name exists and we return true
			return (emp.length != 0);
		} catch (EmployeeDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}

	}

	//NAME: doesEmpFirstNameExist
	//IN:   first name of a employee as a string
	//OUT:  a boolean with result status
	//FUNC:	Returns true if the employee name exists, false otherwise. Returns 
	//		false on error.
	public boolean doesEmpFirstNameExist(String name) 
	{
		try {
			Employee[] emp = EmployeeDAO.findWhereFirstNameEquals(name);

			// If the array isn't empty, the name exists and we return true
			return (emp.length != 0);
		} catch (EmployeeDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	//NAME: checkIfUpdatingEmployee
	//IN:   employee id, first name, last name
	//OUT:  a boolean with result status
	//FUNC:	Returns true if the user is updating their current name in the DB. Returns 
	//		false if they are trying to change their name to a name that already exists.
	public boolean checkIfUpdatingEmployee(int empID, String first, String last) {
		try {
			if (empID != 0) {
				
				System.out.println("CHECK! empID = " + empID);
				System.out.println("first = " + first);
				System.out.println("last = " + last);

				Employee[] emp = EmployeeDAO.findWhereEmployeeIDEquals(empID);
				Employee[] emp1 = EmployeeDAO.findWhereLastNameEquals(last);

				for (int i = 0; i < emp1.length; i++) {
					if (emp1[i].getFirstName().toString().equals(first)) {
						System.out.println("DB! first = " + first);
						System.out.println("DB! last = " + last);
						System.out.println("DB! empID = " + empID);
						if (emp1[i].getEmployeeID() == empID) {
							System.out.println("MADE IT!");
							return true;
						}
						else {
							return false;
						}
					}
				}
				System.out.println("WHY DID I MAKE IT HERE???");
				return true;
			}
			else {
				return false;
			}
		} catch (EmployeeDaoException e) {
			e.printStackTrace();
			System.out.println("WHY DID I MAKE IT HERE???");
		}
		System.out.println("WHY DID I MAKE IT HERE???");
		return false;
		
	}

	//NAME: checkEmployeeDependencies
	//IN:   takes an employee id as an integer
	//OUT:  returns true if there are dependencies and false otherwise
	//FUNC: Checks if the given employee has customers using them
	public boolean checkEmployeeDependencies(int EmpID) {
		for (int i = 0; i < CustomerList.size(); i++) {
			if (CustomerList.get(i).getExternalSalespersonID() == EmpID 
					|| CustomerList.get(i).getForemanID() == EmpID
					|| CustomerList.get(i).getSalespersonID() == EmpID) {
				return true;
			}
		}
		return false;
	}

	//NAME: getEmployeeDependencies
	//IN:   takes an employee id as an integer
	//OUT:  returns an arraylsit of string with all employee dependencies
	//FUNC: Creates a list of all customers routing their jobs to a 
	// 		particular employee.
	public ArrayList<String> getEmployeeDependencies(int EmpID) {
		ArrayList<String> failcode = new ArrayList<String>();
		for (int i = 0; i < CustomerList.size(); i++) {
			if (CustomerList.get(i).getExternalSalespersonID() == EmpID 
					|| CustomerList.get(i).getForemanID() == EmpID
					|| CustomerList.get(i).getSalespersonID() == EmpID) {
				failcode.add(CustomerList.get(i).getCustomerName());
			}
		}
		return failcode;		
	}
	
	public boolean checkEmployeeUsernameUnique(String username, int empID) {
		try {
			Employee[] emp = EmployeeDAO.findWhereUsernameEquals(username);
			if (emp.length == 0) {
				return true;
			}
			else if (emp.length > 1) {
				return false;
			}
			else {
				if (emp[0].getEmployeeID() == empID) {
					return true;
				}
				else {
					return false;
				}
			}
		} catch (EmployeeDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}
	
	public boolean checkEmployeeSSNUnique(String ssn, int empID) {
		try {
			Employee[] emp = EmployeeDAO.findWhereSsnEquals(ssn);
			if (emp.length == 0) {
				return true;
			}
			else if (emp.length > 1) {
				return false;
			}
			else {
				if (emp[0].getEmployeeID() == empID) {
					return true;
				}
				else {
					return false;
				}
			}
		} catch (EmployeeDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	public String getEmployeeFirstName(int i){
		return EmployeeList.get(i).getFirstName();
	}

	public String getEmployeeLastName(int i){
		return EmployeeList.get(i).getLastName();
	}

	public String getEmployeeAddress1(int i){
		return EmployeeList.get(i).getAddress();
	}

	public String getEmployeeAddress2(int i){
		return EmployeeList.get(i).getAddress2();
	}

	public String getEmployeeCity(int i){
		return EmployeeList.get(i).getCity();
	}

	public String getEmployeeState(int i){
		return EmployeeList.get(i).getState();
	}

	public String getEmployeeZip(int i){
		return EmployeeList.get(i).getZip();
	}

	public String getEmployeePhoneNumber(int i){
		return EmployeeList.get(i).getPhoneNumber();
	}

	public String getEmployeeCellNumber(int i){
		return EmployeeList.get(i).getCellNumber();
	}

	public String getEmployeeSSN(int i){
		return EmployeeList.get(i).getSsn();
	}

	public String getUsername(int i){
		return EmployeeList.get(i).getUsername();
	}

	public String getPassword(int i){
		return EmployeeList.get(i).getPassword();
	}
	
	
	
	// LOGIN PANEL STUFF //
	
	public int getEmployeePosition(int empID) {
		return EmployeeList.get(empID).getPositionID();
	}
	
	public int checkEmployeeLogin(String username, String password) {
		try {
			Employee[] emp = EmployeeDAO.findWhereUsernameEquals(username);
			if (emp.length == 1 && emp[0].getPassword().toString().equals(password)) {
				return emp[0].getPositionID();
			}
			else {
				return -1;
			}
		} catch (EmployeeDaoException e) {
			e.printStackTrace();
			return -1;
		}
	}
	
	public String getPositionPermissions(int posID) {
		try {
			Positions pos = PositionsDAO.findByPrimaryKey(posID);
			return pos.getPermissions();
		} catch (PositionsDaoException e) {
			e.printStackTrace();
			return "00000";
		}
	}
	

	public boolean getEmployeeIsDriver(int i) {
		return (EmployeeList.get(i).getIsDriver() == 1);
		//TODO: fix
//		return true;
	}

	public boolean getEmployeeIsForeman(int i) {
		return (EmployeeList.get(i).getIsForeman() == 1);
		//TODO: fix
//		return true;
	}

	public boolean getEmployeeIsSalesperson(int i) {
		return (EmployeeList.get(i).getIsSalesman() == 1);
		//TODO: fix
//		return true;
	}

	public boolean getEmployeeIsExternalSalesperson(int i) {
		return (EmployeeList.get(i).getIsExtSalesman() == 1);
		//TODO: fix
//		return true;
	}
	
	public boolean checkIfPermissionExists(String permission) {
		try {
			Positions[] pos = PositionsDAO.findWherePermissionsEquals(permission);
			if (pos.length == 0) {
				return false;
			}
			else {
				return true;
			}
		} catch (PositionsDaoException e) {
			e.printStackTrace();
			return false;
		}
	}
	
	public String getPermissionName(String permission) {
		try {
			Positions[] pos = PositionsDAO.findWherePermissionsEquals(permission);
			if (pos.length != 0) {
				return pos[0].getName();
			}
			else {
				return "";
			}
		} catch (PositionsDaoException e) {
			e.printStackTrace();
			return "";
		}
		
	}
	
	public void insertPosition(Positions pos){
		try {
			PositionsDAO.insert(pos);
		} catch (PositionsDaoException e) {
			e.printStackTrace();
		}
		this.reloadDB();
	}
	
	public Positions[] getPositions() {
		try {
			Positions[] pos = PositionsDAO.findAll();
			return pos;
		} catch (PositionsDaoException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public String getAccessRights(String name) {
		try {
			Positions[] pos = PositionsDAO.findWhereNameEquals(name);
			return pos[0].getPermissions().toString();
		} catch (PositionsDaoException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public String getAccessRights(int empIndex) {
		try {
			Positions pk = PositionsDAO.findByPrimaryKey(EmployeeList.get(empIndex).getPositionID());
			return pk.getName();
		} catch (PositionsDaoException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public int getPositionID(String name) {
		try {
			Positions[] pos = PositionsDAO.findWhereNameEquals(name);
			return pos[0].getPositionID();
		} catch (PositionsDaoException e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	public boolean checkIfAccessRightNameExists(String name) {
		try {
			Positions[] pos = PositionsDAO.findWhereNameEquals(name);
			if (pos.length == 0) {
				return false;
			}
			else {
				return true;
			}
		} catch (PositionsDaoException e) {
			e.printStackTrace();
			return false;
		}
	}


	//////////////////////////////////////////////
	/////////////// Saving Employee Database /////////////////////////////
	//NAME: updateEmployee
	//IN:   employee primary key and an employee object
	//OUT:  none
	//FUNC: calls to dao to update the employee and then reloads the db
	public void updateEmployee(EmployeePk empPk, Employee emp){	

		try {
			EmployeeDAO.update(empPk, emp);
		} catch (EmployeeDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.reloadDB();
	}

	//NAME: insertEmployee
	//IN:   employee object
	//OUT:  none
	//FUNC: slides a employee via DAO call and then reloads the internal db structure
	public void insertEmployee(Employee emp){
		try {
			EmployeeDAO.insert(emp);
		} catch (EmployeeDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.reloadDB();
	}

	//TODO: REWRITE
	//NAME: employeeAutoIncrement
	//IN:   
	//OUT:  
	//FUNC: 
	public int employeeAutoIncrement() {
		int max = 0;
		for (int i = 0; i < EmployeeList.size(); i++) {
			if (EmployeeList.get(i).getEmployeeID() > max) {
				max = EmployeeList.get(i).getEmployeeID();
			}
		}
		return max + 1;
	}


	///// End Employee Fields //////////




	//NAME: getOrderedItems
	//IN:   order id as an integer
	//OUT:  returns an array of ordereditems corresponding to the order
	//FUNC: takes the order id and returns the ordereditems for this order or 
	//		null if an error occured
	public Ordereditems[] getOrderedItems(int OrderID)
	{

		try {
			Ordereditems[] _ordereditems = OrderedItemsDAO.findWhereOrderIDEquals(OrderID);
			return _ordereditems;
		} catch (OrdereditemsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	//NAME: getOrderedItemsARL
	//IN:   order id as an integer
	//OUT:  returns an arraylist of ordereditems corresponding to the order
	//FUNC: takes the order id and returns the ordereditems for this order or 
	//		null if an error occured
	public ArrayList<Ordereditems> getOrderedItemsARL(int OrderID)
	{
		try {
			Ordereditems[] _ordereditems = OrderedItemsDAO.findWhereOrderIDEquals(OrderID);
			ArrayList<Ordereditems> _orditmARL = new ArrayList<Ordereditems>();
			for(int i = 0; i < _ordereditems.length; i++)
			{
				_orditmARL.add(_ordereditems[i]);
			}
			return _orditmARL;
		} catch (OrdereditemsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

	}

	//NAME: doesCustNameExist
	//IN:   name of a customer as a string
	//OUT:  a boolean with result status
	//FUNC:	Returns true if the customer name exists, false otherwise. Returns 
	//		false on error.
	public boolean doesCustNameExist(String name) 
	{
		try {
			Customers[] cust = CustomersDAO.findWhereCustomerNameEquals(name);

			// If the array isn't empty, the name exists and we return true
			return (cust.length != 0);
		} catch (CustomersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}

	}

	//////////////////////////////////////////////
	/////////////// Saving Customer Database /////////////////////////////
	//NAME: updateCustomers
	//IN:   customer primary key and a customer object
	//OUT:  none
	//FUNC: calls to dao to update the customer and then reloads the db
	public void updateCustomers(CustomersPk custpk, Customers cust1){	

		try {
			CustomersDAO.update(custpk, cust1);
		} catch (CustomersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.reloadDB();
	}

	//NAME: insertCustomer
	//IN:   customer object
	//OUT:  none
	//FUNC: slides a customer via DAO call and then reloads the internal db structure
	public void insertCustomer(Customers cust1){
		try {
			CustomersDAO.insert(cust1);
		} catch (CustomersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.reloadDB();
	}

	//TODO: REWRITE
	//NAME: customerAutoIncrement
	//IN:   
	//OUT:  
	//FUNC: 
	public int customerAutoIncrement() {
		int max = 0;
		for (int i = 0; i < CustomerEditList.size(); i++) {
			if (CustomerEditList.get(i).getCustomerID() > max) {
				max = CustomerEditList.get(i).getCustomerID();
			}
		}
		return max + 1;
	}

	////////////////////////END SETH CHANGES //////////////////////////////

	//////////////////////// MARK'S CHANGES ///////////////////////////////

	//NAME: findOrdersByCustID
	//IN:   customer id as an integer
	//OUT:  returns a null if an error. otherwise returns an array of strings 
	//		with all orders
	//FUNC: Returns a string[] array of all orders by the given customer ID
	public String[] findOrdersByCustID (int id)
	{
		try {
			Orders[] orders = OrdersDAO.findByCustomers(id);
			String[] orderList = new String[orders.length];

			// Adds all the orders to the string array
			for(int i = 0; i < orders.length; i++)
			{
				// Doesn't work because all our entry dates are null
				//			orderList[i] = orders[i].getEnteredTime().toString() + " - ";
				orderList[i] = Integer.toString(orders[i].getOrderID());
			}

			// Returns a string array with the form "Order date - Order ID"
			return orderList;

		} catch (OrdersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// Something went wrong here, so we return null
		String[] test = {"if we got here", "there's something wrong", "very wrong"};
		return test;
	}

	//NAME: getOrderWithID
	//IN:   order id as an int
	//OUT:  order object
	//FUNC: returns an order object given an id; returns null on error
	public Orders getOrderWithID(int id)
	{
		try {
			return OrdersDAO.findByPrimaryKey(id);
		} catch (OrdersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			// Means the order doesn't exist, but we should never get here
			return null;
		}

	}

	//NAME: getEmployeeName
	//IN:   employee id as an integer
	//OUT:  returns a string with a name or a string with an error message
	//FUNC: takes the employee id and returns a string with a name or a 
	//		string with an error message
	public String getEmployeeName(int id)
	{
		try {
			return EmployeeDAO.findByPrimaryKey(id).getLastName();
		} catch (EmployeeDaoException e) {
			// TODO Auto-generated catch block

			e.printStackTrace();
			return "Could not find employee!"; //TODO: bad. should be null.
		}


	}

	//NAME: getDriverList
	//IN:   none
	//OUT:  returns an array of names of all drivers (Strings)
	//FUNC: returns a string array of all names of all drivers
	public String[] getDriverList()
	{
		String[] drivers = new String[DriverList.size()];
		for(int i = 0; i < DriverList.size(); i++)
		{
			drivers[i] = DriverList.get(i).getLastName();
		}

		return drivers;
	}

	//NAME: setDriver
	//IN:   currentDriver: last name of the driver you want in charge of the order
	//		orderID: order ID of the order you want to change the driver of
	//OUT:  none
	//FUNC: Sets the driver in orderID to currentDriver
	public void setDriver(String currentDriver, int orderID)
	{
		try {
			int driverID=0;
			// Returns an array of all the employees with that last name
			// For our purposes we'll assume each last name is unique
			Employee[] driver = EmployeeDAO.findWhereLastNameEquals(currentDriver);

			// If we find the last name, set the driver ID to it's appropriate value, 0 otherwise
			if (driver.length > 0)
				driverID = driver[0].getEmployeeID();
			//			else
			//				driverID = 0;

			for (int i = 0; i< driver.length; i++)
				System.out.println("Driver array: " + driver[i].toString());
			System.out.println("Driver ID: " + driverID);
			// The order want to mess with
			Orders order = OrdersDAO.findByPrimaryKey(orderID);

			// Change the driver ID
			order.setDriverID(driverID);

			// Change it in the DB
			OrdersPk pk = new OrdersPk();
			pk.setOrderID(orderID);
			OrdersDAO.update(pk, order);

		} catch (EmployeeDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (OrdersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	//NAME: setOrderToShipped
	//IN:   takes an order id as an int
	//OUT:  none
	//FUNC: sets the given order status to shipped
	// Sets the order associated with orderID to shipped
	public void setOrderToShipped(int orderID)
	{
		try {
			// The order want to mess with and the current date
			Orders order = OrdersDAO.findByPrimaryKey(orderID);
			Date date = new Date();

			// Sets shipment date to current date and sets status to 1 (shipped)
			order.setShipmentDate(date);
			order.setStatus((short)1); // set order as shipped

			// Change it in the db
			OrdersPk pk = new OrdersPk();
			pk.setOrderID(orderID);
			OrdersDAO.update(pk, order);
		} catch (OrdersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}


	////////////////////////END MARK CHANGES //////////////////////////////

	//NAME: getItemFromList
	//IN:   name of an item
	//OUT:  Returns the item if it was found. Returns null if it wasn't found or if 
	//		db blew up.
	//FUNC: searches for the item by it's name. Returns the item if it was found.
	// 		Returns null if it wasn't found or if db blew up.
	public Items getItemFromList(String itemName)
	{
		try {
			Items[] items = ItemsDAO.findWhereItemNameEquals(itemName);
			// item names are unique, so array should only be 1 if it's found
			if (items.length != 0) {
				return items[0];
			}
		} catch (ItemsDaoException e) {
			e.printStackTrace();
			return null;
		}
		return null;
	}
	
	
	//NAME: getItemFromList
	//IN:   name of an item, price sheet ID
	//OUT:  Returns the item based on given price sheet if it was found.
	//      Returns null if it wasn't found or if db blew up.
	//FUNC: searches for the item by its name. Returns the item if it was found.
	// 		Returns null if it wasn't found or if db blew up.
	public Items getItemFromList(String itemName, int PSid)
	{
//		System.out.println("MEDIATOR.getItemFromList(String itemName, int PSid");
//		System.out.println("itemName=" + itemName + ", PSid=" + PSid);
		// Get the current list of all items using the price sheet with PSid
		// Check itemName linearly through the list until a match is found
		// return the match
		ArrayList<Items> priceList = this.getCompleteListOfPrices(PSid);
		if (!priceList.isEmpty()) {
			for (int i = 0; i < priceList.size(); i++) {
				if (priceList.get(i).getItemName().equals(itemName)) {
					return priceList.get(i);
				}
			}
		}
		
		// We get here if the item was not found, so return nothing
		return null;
	}

	//NAME: getItem
	//IN:   id of an item as an integer
	//OUT:  Returns the item if it was found. Returns null if it wasn't found or if 
	//		db blew up.
	//FUNC: searches for the item id by it's name. Returns the item if it was found.
	// 		Returns null if it wasn't found or if db blew up.
	public Items getItem(int ItemID)
	{
		
		return ItemsMap.get(ItemID);
		
//		try {
//			Items[] _itm = ItemsDAO.findWhereItemIDEquals(ItemID);
//			if(_itm.length==0)
//			{
//				return null;
//			}
//			else
//			{
//				return _itm[0];
//			}
//		} catch (ItemsDaoException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//			return null;
//		}
	}
	
	// Returns the name of the item with the given ID
	public String getItemName(int itemID) {
		return ItemsMap.get(itemID).getItemName();
	}

	//NAME: createNewOrder
	//IN:   integer for customer id; arraylist of all orderedItems on the order; 
	//		the notes for the order
	//OUT:  none
	//FUNC: takes the information about the order. Gathers relevant info for the
	//		order from the customer. then create an order. Then stick all the 
	//		ordered items in the db and connect them to the order 
	public void createNewOrder(int CustomerID, ArrayList<Ordereditems> _ordItms, String notes)
	{
		//		Random randomGenerator = new Random();
		//	int randomInt = randomGenerator.nextInt(100);
		//create new Order
		Date date = new Date();
		Orders _ord = new Orders();
		int orderID = 0;
		_ord.setBillingID(CustomerID);//TODO: this is a bug
		_ord.setCustomerID(CustomerID);
		_ord.setEnteredTime(date);
		_ord.setNotes(notes);
		_ord.setPriceSheetIDNull(true);//TODO:bug

		// TODO: 1 is the default ID since we haven't implemented user login yet
		int enteredByID = 1;
		_ord.setEnteredByID(enteredByID);
		// 0 since the order isn't delivered
		_ord.setStatus((short) 0); 
		// We don't want to assign a driver at this point, so it's set to null
		_ord.setDriverIDNull(true);

		try {
			// Insert the order into the DB
			OrdersDAO.insert(_ord);

			// Find all orders entered at the exact time as the current one
			// Should give back an array of size 1 with the current order
			// We need this because order ID in ordersPk doesn't update correctly
			// when you use the auto_increment feature of firestorm
			Orders[] newOrder = OrdersDAO.findWhereEnteredTimeEquals(date);
			if (newOrder.length == 1) {
				orderID = newOrder[0].getOrderID();
			}
			// If more than one order was entered at the exact same millisecond (nano?),
			// we use the one entered by the current user
			else if (newOrder.length > 1) {
				for (int i = 0; i < newOrder.length; i++) {
					if (newOrder[i].getEnteredByID() == enteredByID)
						orderID = newOrder[i].getOrderID();
				}
			}

			System.out.println("Inserting Order into DB worked!!!!");
		} catch (OrdersDaoException e) {
			System.out.println("Inserting Order into DB failed... miserably");
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		//fill out the missing fields in each Ordereditem
		//and stick em into DB
		for(int i=0; i < _ordItms.size();i++)
		{
			Ordereditems _oitm = _ordItms.get(i);
			_oitm.setOrderID(orderID);

			try {
				OrderedItemsDAO.insert(_oitm);
				System.out.println("Inserting OrderedItems into DB worked!!!!");
			} catch (OrdereditemsDaoException e) 
			{
				System.out.println("Inserting OrderedItems into DB failed... miserably");
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}


	}

	//NAME: modifyOrder
	//IN:   integer for customer id; arraylist of all orderedItems on the order; 
	//		the notes for the order
	//OUT:  none  
	//FUNC: sets new notes, updates the items in the order and if necessary adds
	//		the new items
	public void modifyOrder(int CustomerID, ArrayList<Ordereditems> _ordItms, String notes)
	{
		Ordereditems _oitm = _ordItms.get(0);
		//		Random randomGenerator = new Random();

		Orders _ord;
		try {
			_ord = OrdersDAO.findByPrimaryKey(_oitm.getOrderID());
			_ord.setNotes(notes);
			int orderID = _ord.getOrderID();

			for(int i=0; i < _ordItms.size();i++)
			{

				_oitm = _ordItms.get(i);

				//(if it is a new ordereditem - insert
				if(_oitm.getOrderedItemID() == 0)
				{
					if(_oitm.getQuantityOrdered() > 0)
					{
						_oitm.setOrderID(orderID);

						try 
						{
							OrderedItemsDAO.insert(_oitm);
							System.out.println("Inserting OrderedItems into DB worked!!!!");
						} 
						catch (OrdereditemsDaoException e) 
						{
							System.out.println("Inserting OrderedItems into DB failed... miserably");
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

					}
				}
				//if it already was in DB update
				else
				{
					try
					{
						if(_oitm.getQuantityOrdered() == 0)
						{
							OrderedItemsDAO.delete(_oitm.createPk());
						}

						else
						{
							OrderedItemsDAO.update(_oitm.createPk(), _oitm);
						}
					} 
					catch (OrdereditemsDaoException e) 
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}



				}

			}

		} catch (OrdersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	//NAME: checkIfItemIDExists
	//IN:   ItemID as an integer
	//OUT:  returns true if the ItemID exists, or if error. Else returns false.
	//FUNC: checks if ItemID exists. returns true if the ItemID 
	//		exists, or if error. Else returns false.	
	public boolean checkIfItemIDExists(int ItemID)
	{
		Items itm;
		try {
			itm = ItemsDAO.findByPrimaryKey(ItemID);
			if(itm == null)
			{
				System.out.println("not as easy as i hoped but works");
				return false;
			}
		} catch (ItemsDaoException e) {

			// TODO Auto-generated catch block
			e.printStackTrace();
			return true;
		}
		return true;

	}

	//NAME: checkIfOrderIDExists
	//IN:   orderID as an integer
	//OUT:  returns true if the OrderID exists, or if error. Else returns false.
	//FUNC: checks if orderID exists. returns true if the OrderID 
	//		exists, or if error. Else returns false.
	public boolean checkIfOrderIDExists(int OrderID)
	{

		try {
			Orders ord = OrdersDAO.findByPrimaryKey(OrderID);
			if(ord == null)
			{
				System.out.println("not as easy as i hoped but works");
				return false;
			}
		} catch (OrdersDaoException e) {
			System.out.println("Ouch... OrdersDAO went bellyUP");
			// TODO Auto-generated catch block
			e.printStackTrace();
			return true;
		}

		return true;
	}

	//NAME: checkIfOrderedItemIDExists
	//IN:   orderedItemID as an integer
	//OUT:  returns true if the OrderedItemID exists, or if error. Else returns false.
	//FUNC: checks if orderedItemID exists. returns true if the OrderedItemID 
	//		exists, or if error. Else returns false.
	public boolean checkIfOrderedItemIDExists(int OrdereditemsID)
	{

		try {
			Ordereditems ord = OrderedItemsDAO.findByPrimaryKey(OrdereditemsID);
			if(ord == null)
			{
				System.out.println("not as easy as i hoped but works");
				return false;
			}
		} catch (OrdereditemsDaoException e) {
			System.out.println("Ouch... OrdersDAO went bellyUP");
			// TODO Auto-generated catch block
			e.printStackTrace();
			return true;
		}

		return true;
	}


	//NAME: deleteOrder
	//IN:   integer, orderId
	//OUT:  none
	//FUNC: deletes an order given as an int and then reloads the database
	public void deleteOrder(int OrderID)
	{
		OrdersPk opk = new OrdersPk(OrderID);
		try {
			OrdersDAO.delete(opk);
		} catch (OrdersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		reloadDB();//TODO maybe unnecessary
	}

	//NAME: validateItemName
	//IN:   name of an item as a string
	//OUT:  returns a boolean true if the item exists; otherwise false 
	//FUNC: checks if the name of the item exists. If the name doesn't exist 
	//		returns true. If doesn't or if there's an error returns false
	public boolean validateItemName(String itemName)
	{
		try {
			Items[] itmsArr = ItemsDAO.findWhereItemNameEquals(itemName);
			if (itmsArr.length == 0)
			{
				return true;
			}
			else
			{
				return false;
			}

		} catch (ItemsDaoException e) {
			System.out.println("Ouch... ItemsDAO went bellyUP");
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}

	}

	//NAME: saveItems
	//IN:   arraylist of items
	//OUT:  returns a boolean that signifies the success of failure of the operation
	//FUNC: takes a given arraylist of items, goes through it and adds everything in
	//      it to the database either by update or insert. (tries to use auto-increment).
	//      after all this is done the DB is reloaded.
	public boolean saveItemsFromMasterPS(ArrayList <Items> _itmsArr)
	{
		////////////////////////////////////////////////////
		//go through array and save everything in it to db//
		////////////////////////////////////////////////////
		for(int i = 0; i < _itmsArr.size();i++)
		{//nothing's new, so we just update
			//store in db
			try {
				int itemID = _itmsArr.get(i).getItemID();
				
				// current item status is null
				// so we need the correct item status
				_itmsArr.get(i).setIsActive(ItemsDAO.findByPrimaryKey(itemID).getIsActive());
				
				
				ItemsDAO.update(_itmsArr.get(i).createPk(), _itmsArr.get(i));
			} catch (ItemsDaoException e) {
				System.out.println("Ouch... ItemsDAO went bellyUP");
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}

		}
		this.reloadDB();
		return true;
	}

	
	//NAME: saveItems
	//IN:   arraylist of items
	//OUT:  returns a boolean that signifies the success of failure of the operation
	//FUNC: takes a given arraylist of items, goes through it and adds everything in
	//      it to the database either by update or insert. (tries to use auto-increment).
	//      after all this is done the DB is reloaded.
	public boolean saveItems(ArrayList <Items> _itmsArr)
	{
		////////////////////////////////////////////////////
		//go through array and save everything in it to db//
		////////////////////////////////////////////////////
		for(int i = 0; i < _itmsArr.size();i++)
		{
			//check if it's a new item or no
			if(_itmsArr.get(i).getItemID() == -1)
			{//new
				//generate a new itemID
				//				Random randomGenerator = new Random();
				//				int itemID = randomGenerator.nextInt(1000);
				//				while(checkIfOrderIDExists(itemID))
				//				{
				//					itemID = randomGenerator.nextInt(1000);
				//				}

				//TODO: not the most elegant way of doing it
				//				item.setItemID(itemID);
				Items item = new Items();
				//item.setCost(item_.getCost());
				item.setIsActive(_itmsArr.get(i).getIsActive());
				item.setItemDescription(_itmsArr.get(i).getItemDescription());
				item.setItemName(_itmsArr.get(i).getItemName());
				item.setOtherUnitName(_itmsArr.get(i).getOtherUnitName());
				item.setOtherUnitPrice(_itmsArr.get(i).getOtherUnitPrice());
				item.setUnitName(_itmsArr.get(i).getUnitName());
				item.setUnitPrice(_itmsArr.get(i).getUnitPrice());
				//////////
				///save///
				//////////

				try {
					ItemsDAO.insert(item);
				} catch (ItemsDaoException e) {
					System.out.println("Ouch... ItemsDAO went bellyUP");
					// TODO Auto-generated catch block
					e.printStackTrace();
					return false;
				}
			}
			else
			{//not new

				//store in db
				try {
					ItemsDAO.update(_itmsArr.get(i).createPk(), _itmsArr.get(i));
				} catch (ItemsDaoException e) {
					System.out.println("Ouch... ItemsDAO went bellyUP");
					// TODO Auto-generated catch block
					e.printStackTrace();
					return false;
				}
			}

		}
		this.reloadDB();
		return true;
	}

	//NAME: getCustomerHistory
	//IN:   customer ID in a form of int
	//OUT:  the list of items the customer has purchased during the HistoryInterval
	//FUNC: takes the customerID; get History interval; 
	//      get the list of itmes from customerHistory; remove all beyond the interval;
	public ArrayList<Items> getCustomerHistory(int customerID)
	{
		int HistoryInterval = 0;

		///////////////////////////////////
		// get customer history interval //
		///////////////////////////////////
		CustomersPk pk = new CustomersPk();
		pk.setCustomerID(customerID);
		try {
			HistoryInterval = this.CustomersDAO.findByPrimaryKey(pk).getHistoryInterval();			
		} 
		catch (CustomersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

		///////////////////////////////////////////////////
		//get the list of itmes from the customer History//
		///////////////////////////////////////////////////
		try {
			Customerorderhistory[] CustOrdHist = this.CustomerOrderHistoryDAO.findByCustomers(customerID);

			///////////////////////////////////////////
			// clean customer history list and return//
			///////////////////////////////////////////

			return purgeCustomerOrderHistory(HistoryInterval, CustOrdHist);

		} 
		catch (CustomerorderhistoryDaoException e) {
			e.printStackTrace();
			return null;
		}

	}

	//NAME:  purgeCustomerOrderHistory
	//IN:    customerHistoryInterva in a form of an int; [] of customerorderhistory
	//OUT:	 the list of items the customer has purchased during the HistoryInterval
	//FUNC:  get the list of itmes from customerHistory; remove all beyond the history interval;
	@SuppressWarnings("deprecation")
	public ArrayList<Items> purgeCustomerOrderHistory(int HistoryInterval, Customerorderhistory[] CustOrdHist)
	{
		//create a list of items to be returned as current customer history
		ArrayList<Items> historyItms = new ArrayList<Items>();

		//get cut-off date for the customer history
		Date cut_off_date = new Date();
		int curD = cut_off_date.getDate();
		//System.out.println("cutoffdate before: " + cut_off_date);
		cut_off_date.setDate(curD-HistoryInterval);
//		System.out.println("cutoffdate after: " + cut_off_date);

		for (int i = 0; i < CustOrdHist.length; i++)
		{
			Date old_date = CustOrdHist[i].getLastModified();

			//if the product history is too old delete it
			if(old_date.before(cut_off_date))
			{
				CustomerorderhistoryPk pk = CustOrdHist[i].createPk();
				deleteCustomerOrderHistoryItem(pk);
			}
			//if the product history is not too old add it to the list
			else
			{
				historyItms.add(getItem(CustOrdHist[i].getItemID()));
			}

		}

		return historyItms;
	}

	//NAME: deleteCustomerOrderHistoryItem
	//IN:   Customerorderhistory primary key
	//OUT:  none
	//FUNC: delete Customer Order History Item
	private void deleteCustomerOrderHistoryItem(CustomerorderhistoryPk pk)
	{
		try {
			this.CustomerOrderHistoryDAO.delete(pk);
		} catch (CustomerorderhistoryDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	//NAME: updateCustomerHistory
	//IN:   orderID in a form of int
	//OUT:  none
	//FUNC: takes the orderID; pulls the order shipped date from DB; //TODO: can be a bug if shipped dated is not updated by now!
	//		pulls customer ID from the DB; pulls all items using orderedItems table; 
	//      pulls orderHistory for this customer; for every item in the order, 
	//      go to OrderHistory and updated the ShippedDate on those items.
	public void updateCustomerHistory(int orderID)
	{
		try {
			//get the order; pull shipped date and customer ID
			Orders order = OrdersDAO.findByPrimaryKey(orderID);
			Date shipDate = order.getShipmentDate();
			int customerID = order.getCustomerID();

			//pulls customer history
			Customerorderhistory[] customerHistoryData = this.CustomerOrderHistoryDAO.findByCustomers(customerID);	

			// pull orderedItems
			Ordereditems[] orderedItems = this.OrderedItemsDAO.findByOrders(orderID);

			////////////////////////////////////////////
			// update orderHistory based on the order //  //TODO: this is SLOOOOW
			////////////////////////////////////////////
//			System.out.println("got to line 1535");
			for(int i = 0; i < orderedItems.length; i++)
			{
				boolean not_found_flag = true;

				for (int j = 0; j < customerHistoryData.length; j++)
				{	//if we have a hit
					if(customerHistoryData[j].getItemID() == orderedItems[i].getItemID())
					{	//set proper ship date
						//update in db
						customerHistoryData[j].setLastModified(shipDate);
						this.CustomerOrderHistoryDAO.update(customerHistoryData[j].createPk(),customerHistoryData[j] );
						not_found_flag = false;
					}
				}

//				System.out.println("in the loop not_found_flag: "+not_found_flag);

				if(not_found_flag)
				{//if we don't have a hit create a new entry
					Customerorderhistory histObj = new Customerorderhistory();
					histObj.setCustomerID(customerID);
					histObj.setLastModified(shipDate);
					histObj.setItemID(orderedItems[i].getItemID());
					this.CustomerOrderHistoryDAO.insert(histObj);

				}

			}

		} 

		catch (OrdersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (CustomerorderhistoryDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (OrdereditemsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	//NAME: checkPSTname
	//IN:   name of a pricesheet
	//OUT:  returns true if the name does'nt exits, returns false if it does or call fails
	//FUNC: checks if the priceshet with a given name exists
	public boolean checkPSname(String name)
	{
		try {
			Pricesheets[] _pricesheets = this.PriceSheetsDAO.findWherePriceSheetNameEquals(name);
			if(_pricesheets.length == 0)
			{
				return true;
			}
			return false;
		} catch (PricesheetsDaoException e) {

			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}

	}

	public Pricesheets[] getAllChildrenOfPST(int PSTid)
	{
		try {
			return this.PriceSheetsDAO.findWhereParentPriceSheetIDEquals(PSTid);
		} catch (PricesheetsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
	
	public String getPSname(int PSid)
	{
		try {
			return this.PriceSheetsDAO.findByPrimaryKey(PSid).getPriceSheetName();
		} catch (PricesheetsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	//NAME: createNewPST
	//IN:   name of a pricesheet template as a string
	//OUT:  none
	//FUNC: creats a pricesheet tempalte with a given name
	public void createNewPST(String name)
	{
		try {
			/////////////////
			//save new PST //
			/////////////////
			Pricesheets _new = new Pricesheets();
			_new.setParentPriceSheetID(0);
			_new.setPriceSheetName(name);


			PricesheetsPk _newPk = this.PriceSheetsDAO.insert(_new);
			int _PST_ID = _newPk.getPriceSheetID();

			//////////////////
			//generate PSIs //
			//////////////////
			for(int i =0;i < ItemsList.size(); i++)
			{
				Pricesheetitems _new_psti = new Pricesheetitems();
				_new_psti.setItemID(ItemsList.get(i).getItemID());
				_new_psti.setOtherUnitPrice(0);
				_new_psti.setPrice(0);
				_new_psti.setPriceSheetID(_PST_ID);

				this.PriceSheetItemsDAO.insert(_new_psti);

			}


		} catch (PricesheetsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (PricesheetitemsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.reloadDB();
	}

	//NAME: getPSid
	//IN:   name string of the pricesheet
	//OUT:  returns PricesheetID or -1 if error
	//FUNC: return the price sheet id of a pricesheet given a name
	public int getPSid(String name)
	{

		Pricesheets[] _pricesheets;
		try {
			_pricesheets = this.PriceSheetsDAO.findWherePriceSheetNameEquals(name);

			if(_pricesheets.length == 0)  //#bug 104
			{
				return -1;
			}

			return _pricesheets[0].getPriceSheetID();

		} catch (PricesheetsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}
	}
	
	//NAME: getPSIid
	//IN:   price sheet ID and item ID
	//OUT:  returns PricesheetitemID or -1 if error
	//FUNC: return the price sheet item id given an item ID and pricesheet ID
	public int getPSIid(int psID, int itemID) {
		try {
			// Will be up to as many price sheets as there are
			// So it's still fast since we have to search through maybe 50 tops
			Pricesheetitems[] _psi = this.PriceSheetItemsDAO.findByItems(itemID);
			for (int i = 0; i < _psi.length; i++) {
				if (_psi[i].getPriceSheetID() == psID) {
					return _psi[i].getPriceSheetItemID();
				}
			}
		} catch (PricesheetitemsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		// Error condition
		// means we couldn't find the specified item in the price sheet
		return -1;
	}

	//NAME:	getPSparent
	//IN:	priceSheetID as an int
	//OUT:  returns the PS id of the parent. returns -1 on error.
	//FUNC: returns the PS id of the parent.
	public int getParentPSid(int PSid)
	{

		try 
		{
			System.out.println("PSid = " + PSid + "PSTid = " + this.PriceSheetsDAO.findByPrimaryKey(PSid).getParentPriceSheetID());
			return this.PriceSheetsDAO.findByPrimaryKey(PSid).getParentPriceSheetID();		
		} catch (PricesheetsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}
	}

	//NAME: createNewPS
	//IN:   name of the new pricesheet and it's template
	//OUT:  none
	//FUNC: creates a new pricesheet with a spceific template
	public void createNewPS(String name, String PSTname)
	{
		try {

		if(getPSid(PSTname) > -1)
		{
			Pricesheets _new = new Pricesheets();
			_new.setParentPriceSheetID(getPSid(PSTname));
			_new.setPriceSheetName(name);
			this.PriceSheetsDAO.insert(_new);
		}
		
		
		
		} catch (PricesheetsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


	}

	//NAME:	findPST
	//IN:	PSid as an int
	//OUT:	returns PSTid or -1 if error
	//FUNC:	recursively searches PriceSheet tree for the root
	public int findPST (int PSid)
	{

			int result = this.getParentPSid(PSid);
			if(result == -1)
			{
				return -1;
			}
			if(result == 0)
			{
				return result;
			}
			else
			{
				return findPST(result);
			}

	}
	
	public Pricesheetitems[] getPriceSheetItems(int PSid)
	{
		try {
			return this.PriceSheetItemsDAO.findWherePriceSheetIDEquals(PSid);
		} catch (PricesheetitemsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
	
	// returns an array with item price modifiers from the given price sheet
	public float[] getItemPrices(int psID, int itemID) {
		// size 2 since we only have 2 units
		float[] itemPrices = {DEFAULT_MODIFIER, DEFAULT_MODIFIER};
		try {
			Pricesheetitems[] PST_items;
			PST_items = PriceSheetItemsDAO.findWhereItemIDEquals(itemID);


			//TODO: implement binary search iff items in templates are sorted by item id
			for (int i = 0; i < PST_items.length; i++) {
				if (PST_items[i].getPriceSheetID() == psID) {
					itemPrices[PRICE1_INDEX] = PST_items[i].getPrice();
					itemPrices[PRICE2_INDEX] = PST_items[i].getOtherUnitPrice();
					return itemPrices;
				}
			}
		} catch (PricesheetitemsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		// If we do get here, means either psID or itemID are invalid
		// So we just return the default values (1)
		return itemPrices;
	}


	
	//NAME: getCompleteListOfPrices
	//IN:	integer, price sheet id
	//OUT:	if something went wrong return null. otherwise return a list of all
	//		items with the prices
	//FUNC: 
	public ArrayList<Items> getCompleteListOfPrices(int PSid)
	{
//		System.out.println("MEDIATOR.getCompleteListOfPrices(int PSid)");
//		System.out.println("PSid = " + PSid);
		/////////////////////
		// check if cashed //
		/////////////////////
		ArrayList<Items> _items = this.getFromPriceSheetCache(PSid);
		System.out.println("TRYING TO RETRIVE ITEMS FROM CACHE" +" PSid "+
				PSid+" _itms "+ _items);
		
		if(_items == null)
		{
//			System.out.println("if we got so far we found the bug area");
			////////////////
			//get the data//
			////////////////
			HashMap<Integer, Pricesheetitems> _PSIs = this.getCompletePricesheet(PSid);
			if(_PSIs == null) {return null;	}	
			_items = this.getItemsListCopy();

			
			////////////////////////////////////////////////////////
			//multiply respective prices by the respective factors//
			////////////////////////////////////////////////////////

			for(Items _item:_items)
			{
				//set new price1
				float cur_price1 = _item.getUnitPrice();
				float factor1 = _PSIs.get(_item.getItemID()).getPrice(); //TODO AAAAA bad. won't work properly!!!!!!!!
				_item.setUnitPrice(cur_price1*factor1);
				//set new price2
				float cur_price2 = _item.getOtherUnitPrice();
				float factor2 = _PSIs.get(_item.getItemID()).getOtherUnitPrice(); //TODO AAAAAA bad. won't work properly!!!!!
				_item.setOtherUnitPrice(factor2*cur_price2);

				
			}
			
			//cache this bitch
			System.out.println("tired adding to cache PSid " + PSid + " with items " + _items );
			this.addToPriceSheetCache(PSid, _items);

		}

		for(int i = 0; i < _items.size(); i++)
		{
			System.out.println("i = " + i );
			System.out.println(_items.get(i).toString());
		}
		
	//	this.reloadDB();
		return _items;
	}



	//NAME:	findPST
	//IN:	PSid as an int
	//OUT:	returns the arraylist of all the ancestors of the pricesheet including self. 
	//		returns null if error.
	//FUNC:	returns all the ancestors of the pricesheet IN ORDER FROM ORIGIN TO TEMPLATE
	public ArrayList<Integer> findPSHeritage(int PSid)
	{
		ArrayList<Integer> heritage = new ArrayList<Integer>();
		System.out.println("PSID=" + PSid);
		
		heritage.add(PSid);
		System.out.println("Heritage size is: " + heritage.size());
		PSid = getParentPSid(PSid); if(PSid == -1){return null;}
		System.out.println("PSID=" + PSid);
		while(PSid != 0)
		{
			heritage.add(PSid);
			System.out.println("PSID=" + PSid);
			PSid = getParentPSid(PSid); if(PSid == -1){return null;}
			System.out.println("PSID=" + PSid);
		}


		return heritage;
	}

	//NAME:	HashMapPriceSheetTemplate
	//IN:	PSTid
	//OUT:	HashMap<Integer, Pricesheetitems> of the given PST
	//FUNC:	hashmap the given pst
	public HashMap<Integer, Pricesheetitems> HashMapPriceSheetTemplate (int PSTid)
	{
		HashMap<Integer, Pricesheetitems> _map = new HashMap<Integer, Pricesheetitems>(this.ItemsList.size());
		System.out.println("_map = " + _map);
		Pricesheetitems[] _itms = this.retreivePSTemplateFromCache(PSTid);
		System.out.println("_itms = " + _itms);
		System.out.println(_itms.length);
		for (int i = 0; i < _itms.length; i++)
		{
			System.out.println("i = " +i);
			_map.put(_itms[i].getItemID(), _itms[i]);
		}

		return _map;
	}


	//NAME: getCompletePricesheet
	//IN:	integer, price sheet id
	//OUT:	if something went wrong return null. otherwise return a HashMap with
	//		the values from the complete pricesheet
	//FUNC: the HashMap is <int, Pricesheetitem>; the int is ItemID
	public HashMap<Integer, Pricesheetitems> getCompletePricesheet(int PSid)
	{

		ArrayList<Integer> heritage = findPSHeritage(PSid);
		
		System.out.println("BEGIN: HERITAGE PRINTER");
		for(int i = 0; i < heritage.size(); i++)
		{
			System.out.println("i = "+i+" value = " + heritage.get(i));
		}
		System.out.println("END: HERITAGE PRINTER");

		try {
			if(heritage == null)//error case
			{
				return null;}
			else if(heritage.size() == 1) //already a PST, just hash it
			{
				return this.HashMapPriceSheetTemplate(heritage.get(heritage.size()-1));
			}
			else//some real work here
			{
				
				
				//first get a hashmap of PST
				HashMap<Integer, Pricesheetitems> _map = this.HashMapPriceSheetTemplate(heritage.get(heritage.size()-1));
				
				//then start going backwards through heirarchy dropping all the PSIs in
		
				for(int heritageCounter = heritage.size()-2; heritageCounter >= 0; heritageCounter--)
				{
					System.out.println("heritageCounter " + heritageCounter);
					Pricesheetitems[] _tempPSIs = this.PriceSheetItemsDAO
					.findWherePriceSheetIDEquals(heritage.get(heritageCounter));

					for(int i = 0; i < _tempPSIs.length; i++)
					{
						_map.remove(_tempPSIs[i].getItemID());
						_map.put(_tempPSIs[i].getItemID(), _tempPSIs[i]);
					}
				}

				return _map;

			}



		} catch (PricesheetitemsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}


	}

	
	public ArrayList<Pricesheetitems> getCompletePricesheetPSIs (int PSid)
	{
		HashMap<Integer, Pricesheetitems> _map = this.getCompletePricesheet(PSid);
		ArrayList<Pricesheetitems> _psi = new ArrayList<Pricesheetitems>();
		
		Collection _c = _map.values();
		Iterator itr = _c.iterator();

		while(itr.hasNext())
		{
			_psi.add((Pricesheetitems) itr.next());
		}
		
		
		
		return _psi;
	}
		

	
	//NAME: updateTemplateCache
	//IN: 	void
	//OUT:	void
	//FUNC:	refills the template cache with new templates
	public void refillTemplateCache()
	{
		this.PriceSheetTemplateCache.clear();


		try {
			for (int i = 0; i < PriceSheetTemplates.size(); i++) {
				TemplateCacheItem _cacheItm = new TemplateCacheItem();
				_cacheItm.TemplateID = this.PriceSheetTemplates.get(i).getPriceSheetID();
				_cacheItm.PST_items = PriceSheetItemsDAO.findWherePriceSheetIDEquals(_cacheItm.TemplateID);
				this.PriceSheetTemplateCache.add(_cacheItm);		
			}

		} catch (PricesheetitemsDaoException e) {
			// TODO Auto-generated catch block
			System.out.println("refillTemplateCache failed");
			e.printStackTrace();
		}
	}

	//NAME: retreivePSTemplateFromCache
	//IN:	integer PSTid
	//OUT:	Pricesheetitems[] or null if nothing with such ID is found;
	//FUNC:	grab what you need and go forth. or send out an angry null if nothing is found.
	public Pricesheetitems[] retreivePSTemplateFromCache(int PSTid)
	{
		int i;
		System.out.println("PSTid = " + PSTid);
		for( i = 0; i < this.PriceSheetTemplateCache.size(); i++)
		{
			System.out.println("i= "+ i +" templateID = " + this.PriceSheetTemplateCache.get(i).TemplateID);
			if(this.PriceSheetTemplateCache.get(i).TemplateID == PSTid)
			{
				return this.PriceSheetTemplateCache.get(i).PST_items;
			}

			
		}
		System.out.println("IN rPSTFC i =" + i + " size = " + this.PriceSheetTemplateCache.size());
		return null;
	}
	
	
	//NAME:	getFromPriceSheetCache
	//IN:	
	//OUT:	returns null if not found; returns list of items if found
	//FUNC:	
	public ArrayList<Items> getFromPriceSheetCache(int PSid)
	{
		System.out.println("MEDIATOR.getFromPriceSheetCache(int PSid)");
		System.out.println("PSid = " + PSid);
		if (this.PriceSheetCache.isEmpty()) {
			System.out.println("we got out of evil GFPSC method via empty cahce call ");
			return null;
		}

		//then search for required object
		// We do a reverse search since the most recent items are in the back
		for (int i = PriceSheetCache.size() - 1 ; i >= 0; i--)//TODO: if bug change to i>0
		{
			System.out.println("i= " + i);
			if(PriceSheetCache.get(i).PriceSheetID == PSid)
			{ System.out.println("this shouldn't be happening " + PriceSheetCache.get(i).items);
				return PriceSheetCache.get(i).items;
			}
		}
		
		System.out.println("the for loop never went through");
		return null;
	}

	//NAME:	addToPriceSheetCache
	//IN:	
	//OUT:	
	//FUNC:	
	public void addToPriceSheetCache(int PSid, ArrayList<Items> _itms)
	{	////////////////////////////////////////////////////////////
		// check if cache needs to be cleaned up and if yes do so //
		////////////////////////////////////////////////////////////
		System.out.println("started aTPSC method");
		
		if(PriceSheetCache.size() > MAX_CACHE_SIZE)
		{
			System.out.println("cache to big");
			PriceSheetCache.remove(0);
		}

		////////////////////////////////////////
		// check if the object already exists //
		////////////////////////////////////////

		int cur_loc = checkIfInPriceSheetCache(PSid);
		if(cur_loc != -1)
		{
			System.out.println("object exists");
			//move to the tail
			PriceSheetCache.add(PriceSheetCache.get(cur_loc));
			PriceSheetCache.remove(cur_loc);
		}

		///////////////////
		// if it doesn't //
		///////////////////
		else
		{
			//create new object
			System.out.println("new object");
			CompletePricesheetCacheItem _tmp = new CompletePricesheetCacheItem();
			_tmp.PriceSheetID = PSid;
			_tmp.items = _itms;

			// add it

			PriceSheetCache.add(_tmp);
		}


		System.out.println("BEGIN PRINT CACHE");
		for(int i = 0; i < PriceSheetCache.size(); i++)
		{
			System.out.println("i = " + i + " psid = " + PriceSheetCache.get(i).PriceSheetID);
		}
		System.out.println("END PRINT CACHE");

	}

	//NAME:	checkIfInPriceSheetCache
	//IN:	
	//OUT:	returns -1 if not in; otherwise returns the index
	//FUNC:	checks if the list is empty, then if not searches for the required item
	public int checkIfInPriceSheetCache(int PSid)
	{	
		//////////////////
		//check if empty//
		//////////////////
		if (this.PriceSheetCache.isEmpty()) {return -1;}

		///////////////////////////////////
		//then search for required object//
		///////////////////////////////////

		//we do reversed search because the most recent items are in the back
		for (int i = PriceSheetCache.size() - 1 ; i >= 0; i--)//TODO: if bug change to i>0
		{
			if(PriceSheetCache.get(i).PriceSheetID == PSid)
			{return i;}
		}
		return -1;
	}

	public void savePSmodifications(ArrayList<Pricesheetitems> modQ)
	{
		for (int i = 0; i < modQ.size(); i++)
		{
			try {
				PriceSheetItemsDAO.update(modQ.get(i).createPk(), modQ.get(i));
				this.reloadDB();
			} catch (PricesheetitemsDaoException e) {
				System.out.println("modification of an PSI failed");	
				e.printStackTrace();
			} 
		}
	}
	
	public void savePSadditions(ArrayList<Pricesheetitems> addQ)
	{
		for (int i = 0; i < addQ.size() ; i++)
		{
			try {
				PriceSheetItemsDAO.insert(addQ.get(i));
				this.reloadDB();
			} catch (PricesheetitemsDaoException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	
	// Checks against the current cache to see if the item is inactive or not
	// Returns true if the item is currently active
	// Returns false if it's inactive
	// Uses binary search algorithm to find the item quickly and efficiently
	public boolean isItemInactiveInDB(int itemID) {
		int low = 0;
        int high = ItemsList.size()-1;
        int mid;

        while(low <= high) {
            mid = (low + high) / 2;

            if(ItemsList.get(mid).getItemID() < itemID)
                low = mid + 1;
            else if(ItemsList.get(mid).getItemID() > itemID)
                high = mid - 1;
            else
            	// Means we've found the item
            	// Returns true if inactive, false if active
                return ItemsList.get(mid).getIsActive() == 0;
        }

        // Returns false if the item wasn't found
		return false;
	}
	
	public Customers[] getAllCustomersThatUseThisPriceSheet(int PSid){
		
		try {
			return CustomersDAO.findByPricesheets(PSid);
		} catch (CustomersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		
	}
	
	public Customers[] getAllCustomersThatUseThisPriceSheetTemplate(int PSTid)
	{
		try {
			return CustomersDAO.findByPricesheets2(PSTid);
		} catch (CustomersDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
	
	public Pricesheets[] getAllPricesheetsThatAreChildrenOf(int PSid)
	{
		try {
			return PriceSheetsDAO.findWhereParentPriceSheetIDEquals(PSid);
		} catch (PricesheetsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
 	
	public void deletPriceSheet (int PSid)
	{
		try {
		PricesheetsPk pk = new PricesheetsPk();
		pk.setPriceSheetID(PSid);
		
			PriceSheetsDAO.delete(pk);
		} catch (PricesheetsDaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	//dont' touch this
	//can't touch this
	//duh nuh nuh nuh nuh chshh chshh duh nuh chshh chshh duh nuh chshh chshh
	//duh nuh nuh nuh nuh chshh chshh duh nuh chshh chshh duh nuh chshh chshh
	//can't touch this
}


